package androidparser.bean;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

public class ParseResource {

	public static final Set<String> FOCUS_LAYOUT_ELEMENT = new HashSet<String>();

	public HashMap<String, List<LayoutView>> m_layout_map = new HashMap<String, List<LayoutView>>();
	public Set<String> m_layout_property_set = new HashSet<String>();
	public Set<String> m_layout_element_set = new HashSet<String>();
	public List<ActivityProperty> m_activity_list = new ArrayList<ActivityProperty>();
	public Set<String> m_activity_property_set = new HashSet<String>();
	
	public String m_project_dir;
	public String m_output_dir;
	public String m_package_name;
	
	
	static {
		FOCUS_LAYOUT_ELEMENT.add("LinearLayout");
		FOCUS_LAYOUT_ELEMENT.add("RelativeLayout");
		FOCUS_LAYOUT_ELEMENT.add("TableLayout");
		FOCUS_LAYOUT_ELEMENT.add("FrameLayout");
		FOCUS_LAYOUT_ELEMENT.add("ImageView");
		FOCUS_LAYOUT_ELEMENT.add("ListView");
		FOCUS_LAYOUT_ELEMENT.add("WebView");
		FOCUS_LAYOUT_ELEMENT.add("ScrollView");
		FOCUS_LAYOUT_ELEMENT.add("TextView");
		FOCUS_LAYOUT_ELEMENT.add("ViewFlipper");
		FOCUS_LAYOUT_ELEMENT.add("ProgressBar");
		FOCUS_LAYOUT_ELEMENT.add("ImageButton");
		FOCUS_LAYOUT_ELEMENT.add("CheckBox");
		FOCUS_LAYOUT_ELEMENT.add("fragment");
		FOCUS_LAYOUT_ELEMENT.add("EditText");
		FOCUS_LAYOUT_ELEMENT.add("GridView");
		FOCUS_LAYOUT_ELEMENT.add("HorizontalScrollView");
		FOCUS_LAYOUT_ELEMENT.add("ExpandableListView");
		FOCUS_LAYOUT_ELEMENT.add("include");
	}

	public static void toAnalysisFiles(String path) throws IOException,
			XmlPullParserException {
		File projectDir = new File(path);
		if (!projectDir.exists()) {
			throw new IOException(projectDir.getPath() + " doesn't exist!");
		}
		
		ParseResource parser = new ParseResource(path);
		
		File[] layoutFiles = parser.getLayoutFolder(projectDir);

		for (File file : layoutFiles) {
			for (File xmlFile : file.listFiles()) {
				if (xmlFile.getName().contains("xml")) {
					parser.parserLayoutFile(xmlFile);
				}
			}
		}

		OutputControl layoutIDFile = new OutPutLayoutID(parser,"LayoutIDs.csv");
		layoutIDFile.writeToFile();
		
		for(String view:FOCUS_LAYOUT_ELEMENT){
			OutputControl layoutViewFile = new OutputViewProperty(parser,view);
			layoutViewFile.writeToFile();
		}
		
		OutputControl activityFile = new OutputActivityProperty(parser,"Activties.csv");
		activityFile.writeToFile();
	}

	
	public ParseResource(String projectDir){
		m_project_dir = projectDir;
		try {
			parseAndroidManifest();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		m_output_dir = "D:\\analysis\\" + m_package_name + "\\";
		
		new File(m_output_dir).mkdirs();
	}
	
	
	private File[] getLayoutFolder(File projectDir) {
		File[] rootFiles = projectDir.listFiles();
		File resFolder = null;
		List<File> layoutFiles = new ArrayList<File>();

		for (File subfile : rootFiles) {
			if (subfile.isDirectory()
					&& subfile.getName().equalsIgnoreCase("res")) {
				resFolder = subfile;
			}
		}

		if (resFolder == null) {
			return layoutFiles.toArray(new File[0]);
		}

		for (File subfile : resFolder.listFiles()) {
			if (subfile.isDirectory() && subfile.getName().contains("layout")) {
				layoutFiles.add(subfile);
			}
		}

		return layoutFiles.toArray(new File[0]);
	}

	private void parserLayoutFile(File layoutFile)
			throws XmlPullParserException, IOException {
		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		XmlPullParser xpp = null;
		xpp = factory.newPullParser();
		InputStream is = new FileInputStream(layoutFile);
		xpp.setInput(is, "UTF-8");
		int eventType = xpp.getEventType();
		List<LayoutView> views = new ArrayList<LayoutView>();

		while (eventType != XmlPullParser.END_DOCUMENT) {
			String nodeName = xpp.getName();
			if (eventType == XmlPullParser.START_TAG) {
				System.out.println(nodeName + " has attribute number:"
						+ xpp.getAttributeCount());
				LayoutView property = new LayoutView();
				property.m_view_name = nodeName;
				for (int i = 0; i < xpp.getAttributeCount(); i++) {
					String key = xpp.getAttributeName(i);
					String value = xpp.getAttributeValue(i);
					property.m_view_property.put(key, value);
					m_layout_property_set.add(key);
				}
				m_layout_element_set.add(nodeName);
				views.add(property);
			}
			eventType = xpp.next();
		}
		m_layout_map.put(layoutFile.getPath(), views);
	}

	private void parseAndroidManifest() throws XmlPullParserException, IOException{
		File fs = new File(m_project_dir + "\\AndroidManifest.xml");
		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		XmlPullParser xpp = null;
		xpp = factory.newPullParser();
		InputStream is = new FileInputStream(fs);
		xpp.setInput(is, "UTF-8");
		
		int eventType = xpp.getEventType();
		while (eventType != XmlPullParser.END_DOCUMENT) {
			String nodeName = xpp.getName();
			if (eventType == XmlPullParser.START_TAG) {
				System.out.println(nodeName);
				if(nodeName.equals("manifest")){
					for (int i = 0; i < xpp.getAttributeCount(); i++) {
						if(xpp.getAttributeName(i).equals("package")){
							m_package_name = xpp.getAttributeValue(i);
						}
					}
				}
				
				if(nodeName.equals("activity")){
					ActivityProperty activity_property = new ActivityProperty();
					for (int i = 0; i < xpp.getAttributeCount(); i++) {
						activity_property.m_property_map.put(xpp.getAttributeName(i),xpp.getAttributeValue(i));
						m_activity_property_set.add(xpp.getAttributeName(i));
					}
					m_activity_list.add(activity_property);
				}
			}
			eventType = xpp.next();
		}
		
		m_activity_property_set.remove("android:name");
		
	}
	
}
